import logging
from enum import Enum, auto
from pathlib import Path
from typing import Optional

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')


class VmdType(Enum):
    DoNothing = auto()
    ReserveStart = auto()
    ReserveEnd = auto()


class TxtParser:
    def __init__(self):
        # 获取 vmd 所有的帧数
        self._boneframe_count: int = 0
        self._real_boneframe_count: int = 0
        self._real_morphframe_count: int = 0

    def process(self, vmd_path: Path) -> list[str]:
        # 如果文件不存在或者不以txt结尾则抛出异常
        if not vmd_path.exists() or vmd_path.suffix != '.txt':
            raise FileNotFoundError(f"File not found or not a txt file: {vmd_path}")

        self._output_data: list[str] = []
        self._data: list[str] = vmd_path.read_text(encoding='utf-8', errors='ignore').split('\n')
        if not self._data:
            raise ValueError(f"File is empty: {vmd_path}")

        def process_one_group(data: list[str]) -> list[str]:
            # 原始数据列表
            original_data = [line.strip() for line in data]

            # 解析CSV数据为列表
            parsed_data = [line.split(',') for line in original_data]

            # 将数据按照第二列进行倒序排列
            sorted_data = sorted(parsed_data, key=lambda x: int(x[1]), reverse=True)
            lastest_number: int = int(sorted_data[0][1]) if sorted_data else 0

            # 更新第二列的数值，将其加上add_number，并倒序更新索引
            updated_data = []
            for i, row in enumerate(sorted_data):
                new_row = row[:]
                new_row[1] = str(lastest_number + i + 1)
                updated_data.append(new_row)

            # 将数据重新合并为CSV格式的字符串
            modified_data = [','.join(row) for row in updated_data]

            # 返回合并的结果集（原始数据 + 修改后的数据）
            return original_data + modified_data

        current_name: Optional[str] = None
        current_status: VmdType = VmdType.DoNothing
        bone_group: list[str] = []
        for line in self._data:
            if line.startswith('boneframe_ct'):
                self._boneframe_count = int(line.split(':,')[1])
                self._output_data.append(line)
                logging.debug(f"boneframe_count: {self._boneframe_count}")
            elif line.startswith('bone_name,frame_num'):
                current_status = VmdType.ReserveStart
                self._output_data.append(line)
                self._is_current_bone = True
                self._is_current_morph = False
            elif line.startswith('morphframe_ct'):
                current_status = VmdType.ReserveEnd
                self._output_data.extend(process_one_group(bone_group))
                bone_group.clear()
                count = int(line.split(':,')[1])
                self._output_data.append(line)
                logging.debug(f"morphframe_count: {count}")
                self._is_current_bone = False
                self._is_current_morph = True
            elif line.startswith('morph_name,frame_num,value'):
                current_status = VmdType.ReserveStart
                self._output_data.append(line)
            elif line.startswith('camframe_ct'):
                current_status = VmdType.ReserveEnd
                self._output_data.append(line)
            elif current_status == VmdType.ReserveStart:
                bone_name = line.split(',')[0]

                if not current_name:
                    current_name = bone_name
                elif current_name == bone_name:
                    bone_group.append(line)
                elif current_name != bone_name:
                    current_name = bone_name

                    # 如果只有一个骨骼帧添加多个会鬼畜
                    if len(bone_group) == 1:
                        if self._is_current_bone:
                            self._real_boneframe_count += len(bone_group)
                        elif self._is_current_morph:
                            self._real_morphframe_count += len(bone_group)
                        else:
                            raise ValueError("Unknown type")

                        self._output_data.append(bone_group[0])
                        bone_group.clear()
                        bone_group.append(line)
                        continue

                    if self._is_current_bone:
                        self._real_boneframe_count += len(bone_group) * 2
                    elif self._is_current_morph:
                        self._real_morphframe_count += len(bone_group) * 2
                    else:
                        raise ValueError("Unknown type")

                    self._output_data.extend(process_one_group(bone_group))
                    bone_group.clear()
                    bone_group.append(line)
            elif current_status == VmdType.ReserveEnd or current_status == VmdType.DoNothing:
                current_status = VmdType.DoNothing
                self._output_data.append(line)

        # 寻找包含boneframe_ct的行
        for index, each in enumerate(self._output_data):
            if each.startswith('boneframe_ct'):
                self._output_data[index] = f'boneframe_ct:,{self._real_boneframe_count + 1}'
                break

        # 寻找包含morphframe_ct的行
        for index, each in enumerate(self._output_data):
            if each.startswith('morphframe_ct'):
                self._output_data[index] = f'morphframe_ct:,{self._real_morphframe_count + 1}'
                break
        return self._output_data


if __name__ == '__main__':
    from pprint import pprint

    vmd_path = r"D:\舞蹈\动作\张元英转圈\张元英转圈.txt"
    t = TxtParser()
    pprint(t.process(Path(vmd_path)))
